home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 21 / AACD 21.iso / AACD / Utilities / Ghostscript / src / gxclutil.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-01  |  18.2 KB  |  655 lines

  1. /* Copyright (C) 1998 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of AFPL Ghostscript.
  4.   
  5.   AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author or
  6.   distributor accepts any responsibility for the consequences of using it, or
  7.   for whether it serves any particular purpose or works at all, unless he or
  8.   she says so in writing.  Refer to the Aladdin Free Public License (the
  9.   "License") for full details.
  10.   
  11.   Every copy of AFPL Ghostscript must include a copy of the License, normally
  12.   in a plain ASCII text file named PUBLIC.  The License grants you the right
  13.   to copy, modify and redistribute AFPL Ghostscript, but only under certain
  14.   conditions described in the License.  Among other things, the License
  15.   requires that the copyright notice and this notice be preserved on all
  16.   copies.
  17. */
  18.  
  19. /*$Id: gxclutil.c,v 1.2.2.1 2000/11/09 23:36:53 rayjj Exp $ */
  20. /* Command list writing utilities. */
  21.  
  22. #include "memory_.h"
  23. #include "string_.h"
  24. #include "gx.h"
  25. #include "gp.h"
  26. #include "gpcheck.h"
  27. #include "gserrors.h"
  28. #include "gxdevice.h"
  29. #include "gxdevmem.h"        /* must precede gxcldev.h */
  30. #include "gxcldev.h"
  31. #include "gxclpath.h"
  32. #include "gsparams.h"
  33.  
  34. /* ---------------- Statistics ---------------- */
  35.  
  36. #ifdef DEBUG
  37. const char *const cmd_op_names[16] =
  38. {cmd_op_name_strings};
  39. private const char *const cmd_misc_op_names[16] =
  40. {cmd_misc_op_name_strings};
  41. private const char *const cmd_misc2_op_names[16] =
  42. {cmd_misc2_op_name_strings};
  43. private const char *const cmd_segment_op_names[16] =
  44. {cmd_segment_op_name_strings};
  45. private const char *const cmd_path_op_names[16] =
  46. {cmd_path_op_name_strings};
  47. const char *const *const cmd_sub_op_names[16] =
  48. {cmd_misc_op_names, 0, 0, 0, 0, 0, 0, 0,
  49.  0, 0, 0, 0,
  50.  0, cmd_misc2_op_names, cmd_segment_op_names, cmd_path_op_names
  51. };
  52. struct stats_cmd_s {
  53.     ulong op_counts[256];
  54.     ulong op_sizes[256];
  55.     ulong tile_reset, tile_found, tile_added;
  56.     ulong same_band, other_band;
  57. } stats_cmd;
  58. extern ulong stats_cmd_diffs[5];    /* in gxclpath.c */
  59. int
  60. cmd_count_op(int op, uint size)
  61. {
  62.     stats_cmd.op_counts[op]++;
  63.     stats_cmd.op_sizes[op] += size;
  64.     if (gs_debug_c('L')) {
  65.     const char *const *sub = cmd_sub_op_names[op >> 4];
  66.  
  67.     if (sub)
  68.         dlprintf2(", %s(%u)\n", sub[op & 0xf], size);
  69.     else
  70.         dlprintf3(", %s %d(%u)\n", cmd_op_names[op >> 4], op & 0xf,
  71.               size);
  72.     fflush(dstderr);
  73.     }
  74.     return op;
  75. }
  76. void
  77. cmd_uncount_op(int op, uint size)
  78. {
  79.     stats_cmd.op_counts[op]--;
  80.     stats_cmd.op_sizes[op] -= size;
  81. }
  82. #endif
  83.  
  84. /* Print statistics. */
  85. #ifdef DEBUG
  86. void
  87. cmd_print_stats(void)
  88. {
  89.     int ci, cj;
  90.  
  91.     dlprintf3("[l]counts: reset = %lu, found = %lu, added = %lu\n",
  92.           stats_cmd.tile_reset, stats_cmd.tile_found,
  93.           stats_cmd.tile_added);
  94.     dlprintf5("     diff 2.5 = %lu, 3 = %lu, 4 = %lu, 2 = %lu, >4 = %lu\n",
  95.           stats_cmd_diffs[0], stats_cmd_diffs[1], stats_cmd_diffs[2],
  96.           stats_cmd_diffs[3], stats_cmd_diffs[4]);
  97.     dlprintf2("     same_band = %lu, other_band = %lu\n",
  98.           stats_cmd.same_band, stats_cmd.other_band);
  99.     for (ci = 0; ci < 0x100; ci += 0x10) {
  100.     const char *const *sub = cmd_sub_op_names[ci >> 4];
  101.  
  102.     if (sub != 0) {
  103.         dlprintf1("[l]  %s =", cmd_op_names[ci >> 4]);
  104.         for (cj = ci; cj < ci + 0x10; cj += 2)
  105.         dprintf6("\n\t%s = %lu(%lu), %s = %lu(%lu)",
  106.              sub[cj - ci],
  107.              stats_cmd.op_counts[cj], stats_cmd.op_sizes[cj],
  108.              sub[cj - ci + 1],
  109.            stats_cmd.op_counts[cj + 1], stats_cmd.op_sizes[cj + 1]);
  110.     } else {
  111.         ulong tcounts = 0, tsizes = 0;
  112.  
  113.         for (cj = ci; cj < ci + 0x10; cj++)
  114.         tcounts += stats_cmd.op_counts[cj],
  115.             tsizes += stats_cmd.op_sizes[cj];
  116.         dlprintf3("[l]  %s (%lu,%lu) =\n\t",
  117.               cmd_op_names[ci >> 4], tcounts, tsizes);
  118.         for (cj = ci; cj < ci + 0x10; cj++)
  119.         if (stats_cmd.op_counts[cj] == 0)
  120.             dputs(" -");
  121.         else
  122.             dprintf2(" %lu(%lu)", stats_cmd.op_counts[cj],
  123.                  stats_cmd.op_sizes[cj]);
  124.     }
  125.     dputs("\n");
  126.     }
  127. }
  128. #endif /* DEBUG */
  129.  
  130. /* ---------------- Writing utilities ---------------- */
  131.  
  132. /* Write the commands for one band or band range. */
  133. private int    /* ret 0 all ok, -ve error code, or +1 ok w/low-mem warning */
  134. cmd_write_band(gx_device_clist_writer * cldev, int band_min, int band_max,
  135.            cmd_list * pcl, byte cmd_end)
  136. {
  137.     const cmd_prefix *cp = pcl->head;
  138.     int code_b = 0;
  139.     int code_c = 0;
  140.  
  141.     if (cp != 0 || cmd_end != cmd_opv_end_run) {
  142.     clist_file_ptr cfile = cldev->page_cfile;
  143.     clist_file_ptr bfile = cldev->page_bfile;
  144.     cmd_block cb;
  145.     byte end = cmd_count_op(cmd_end, 1);
  146.  
  147.     if (cfile == 0 || bfile == 0)
  148.          return_error(gs_error_ioerror);
  149.     cb.band_min = band_min;
  150.     cb.band_max = band_max;
  151.     cb.pos = clist_ftell(cfile);
  152.     if_debug3('l', "[l]writing for bands (%d,%d) at %ld\n",
  153.           band_min, band_max, cb.pos);
  154.     clist_fwrite_chars(&cb, sizeof(cb), bfile);
  155.     if (cp != 0) {
  156.         pcl->tail->next = 0;    /* terminate the list */
  157.         for (; cp != 0; cp = cp->next) {
  158. #ifdef DEBUG
  159.         if ((const byte *)cp < cldev->cbuf ||
  160.             (const byte *)cp >= cldev->cend ||
  161.             cp->size > cldev->cend - (const byte *)cp
  162.             ) {
  163.             lprintf1("cmd_write_band error at 0x%lx\n", (ulong) cp);
  164.             return_error(gs_error_Fatal);
  165.         }
  166. #endif
  167.         clist_fwrite_chars(cp + 1, cp->size, cfile);
  168.         }
  169.         pcl->head = pcl->tail = 0;
  170.     }
  171.     clist_fwrite_chars(&end, 1, cfile);
  172.     process_interrupts();
  173.     code_b = clist_ferror_code(bfile);
  174.     code_c = clist_ferror_code(cfile);
  175.     if (code_b < 0)
  176.         return_error(code_b);
  177.     if (code_c < 0)
  178.         return_error(code_c); 
  179.     }
  180.     return code_b | code_c;
  181. }
  182.  
  183. /* Write out the buffered commands, and reset the buffer. */
  184. int    /* ret 0 all-ok, -ve error code, or +1 ok w/low-mem warning */
  185. cmd_write_buffer(gx_device_clist_writer * cldev, byte cmd_end)
  186. {
  187.     int nbands = cldev->nbands;
  188.     gx_clist_state *pcls;
  189.     int band;
  190.     int code = cmd_write_band(cldev, cldev->band_range_min,
  191.                   cldev->band_range_max,
  192.                   &cldev->band_range_list, cmd_opv_end_run);
  193.     int warning = code;
  194.  
  195.     for (band = 0, pcls = cldev->states;
  196.      code >= 0 && band < nbands; band++, pcls++
  197.      ) {
  198.     code = cmd_write_band(cldev, band, band, &pcls->list, cmd_end);
  199.     warning |= code;
  200.     }
  201.     /* If an error occurred, finish cleaning up the pointers. */
  202.     for (; band < nbands; band++, pcls++)
  203.     pcls->list.head = pcls->list.tail = 0;
  204.     cldev->cnext = cldev->cbuf;
  205.     cldev->ccl = 0;
  206. #ifdef DEBUG
  207.     if (gs_debug_c('l'))
  208.     cmd_print_stats();
  209. #endif
  210.     return_check_interrupt(code != 0 ? code : warning);
  211. }
  212.  
  213. /*
  214.  * Add a command to the appropriate band list, and allocate space for its
  215.  * data.  Return the pointer to the data area.  If an error or (low-memory
  216.  * warning) occurs, set cldev->error_code and return 0.
  217.  */
  218. #define cmd_headroom (sizeof(cmd_prefix) + arch_align_ptr_mod)
  219. byte *
  220. cmd_put_list_op(gx_device_clist_writer * cldev, cmd_list * pcl, uint size)
  221. {
  222.     byte *dp = cldev->cnext;
  223.  
  224.     if (size + cmd_headroom > cldev->cend - dp) {
  225.     if ((cldev->error_code =
  226.            cmd_write_buffer(cldev, cmd_opv_end_run)) != 0) {
  227.         if (cldev->error_code < 0)
  228.         cldev->error_is_retryable = 0;    /* hard error */
  229.         else {
  230.         /* upgrade lo-mem warning into an error */
  231.         if (!cldev->ignore_lo_mem_warnings)
  232.             cldev->error_code = gs_note_error(gs_error_VMerror);
  233.         cldev->error_is_retryable = 1;
  234.         }
  235.         return 0;
  236.     }
  237.     else
  238.         return cmd_put_list_op(cldev, pcl, size);
  239.     }
  240.     if (cldev->ccl == pcl) {    /* We're adding another command for the same band. */
  241.     /* Tack it onto the end of the previous one. */
  242.     cmd_count_add1(stats_cmd.same_band);
  243. #ifdef DEBUG
  244.     if (pcl->tail->size > dp - (byte *) (pcl->tail + 1)) {
  245.         lprintf1("cmd_put_list_op error at 0x%lx\n", (ulong) pcl->tail);
  246.     }
  247. #endif
  248.     pcl->tail->size += size;
  249.     } else {
  250.     /* Skip to an appropriate alignment boundary. */
  251.     /* (We assume the command buffer itself is aligned.) */
  252.     cmd_prefix *cp = (cmd_prefix *)
  253.         (dp + ((cldev->cbuf - dp) & (arch_align_ptr_mod - 1)));
  254.  
  255.     cmd_count_add1(stats_cmd.other_band);
  256.     dp = (byte *) (cp + 1);
  257.     if (pcl->tail != 0) {
  258. #ifdef DEBUG
  259.         if (pcl->tail < pcl->head ||
  260.         pcl->tail->size > dp - (byte *) (pcl->tail + 1)
  261.         ) {
  262.         lprintf1("cmd_put_list_op error at 0x%lx\n",
  263.              (ulong) pcl->tail);
  264.         }
  265. #endif
  266.         pcl->tail->next = cp;
  267.     } else
  268.         pcl->head = cp;
  269.     pcl->tail = cp;
  270.     cldev->ccl = pcl;
  271.     cp->size = size;
  272.     }
  273.     cldev->cnext = dp + size;
  274.     return dp;
  275. }
  276. #ifdef DEBUG
  277. byte *
  278. cmd_put_op(gx_device_clist_writer * cldev, gx_clist_state * pcls, uint size)
  279. {
  280.     if_debug3('L', "[L]band %d: size=%u, left=%u",
  281.           (int)(pcls - cldev->states),
  282.           size, (uint) (cldev->cend - cldev->cnext));
  283.     return cmd_put_list_op(cldev, &pcls->list, size);
  284. }
  285. #endif
  286.  
  287. /* Add a command for a range of bands. */
  288. byte *
  289. cmd_put_range_op(gx_device_clist_writer * cldev, int band_min, int band_max,
  290.          uint size)
  291. {
  292.     if_debug4('L', "[L]band range(%d,%d): size=%u, left=%u",
  293.           band_min, band_max, size,
  294.           (uint)(cldev->cend - cldev->cnext));
  295.     if (cldev->ccl != 0 && 
  296.     (cldev->ccl != &cldev->band_range_list ||
  297.      band_min != cldev->band_range_min ||
  298.      band_max != cldev->band_range_max)
  299.     ) {
  300.     if ((cldev->error_code = cmd_write_buffer(cldev, cmd_opv_end_run)) != 0) {
  301.         if (cldev->error_code < 0)
  302.         cldev->error_is_retryable = 0;    /* hard error */
  303.         else {
  304.         /* upgrade lo-mem warning into an error */
  305.         cldev->error_code = gs_error_VMerror;
  306.         cldev->error_is_retryable = 1;
  307.         }
  308.         return 0;
  309.     }
  310.     cldev->band_range_min = band_min;
  311.     cldev->band_range_max = band_max;
  312.     }
  313.     return cmd_put_list_op(cldev, &cldev->band_range_list, size);
  314. }
  315.  
  316. /* Write a variable-size positive integer. */
  317. int
  318. cmd_size_w(register uint w)
  319. {
  320.     register int size = 1;
  321.  
  322.     while (w > 0x7f)
  323.     w >>= 7, size++;
  324.     return size;
  325. }
  326. byte *
  327. cmd_put_w(register uint w, register byte * dp)
  328. {
  329.     while (w > 0x7f)
  330.     *dp++ = w | 0x80, w >>= 7;
  331.     *dp = w;
  332.     return dp + 1;
  333. }
  334.  
  335. /* Define the encodings of the different settable colors. */
  336. const clist_select_color_t
  337.     clist_select_color0 = {cmd_op_set_color0, cmd_opv_delta2_color0, 0},
  338.     clist_select_color1 = {cmd_op_set_color1, cmd_opv_delta2_color1, 0},
  339.     clist_select_tile_color0 = {cmd_op_set_color0, cmd_opv_delta2_color0, 1},
  340.     clist_select_tile_color1 = {cmd_op_set_color1, cmd_opv_delta2_color1, 1};
  341. int
  342. cmd_put_color(gx_device_clist_writer * cldev, gx_clist_state * pcls,
  343.           const clist_select_color_t * select,
  344.           gx_color_index color, gx_color_index * pcolor)
  345. {
  346.     byte *dp;
  347.     long diff = (long)color - (long)(*pcolor);
  348.     byte op, op_delta2;
  349.     int code;
  350.  
  351.     if (diff == 0)
  352.     return 0;
  353.     if (select->tile_color) {
  354.     code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_set_tile_color, 1);
  355.     if (code < 0)
  356.         return code;
  357.     }
  358.     op = select->set_op;
  359.     op_delta2 = select->delta2_op;
  360.     if (color == gx_no_color_index) {
  361.     /*
  362.      * We must handle this specially, because it may take more
  363.      * bytes than the color depth.
  364.      */
  365.     code = set_cmd_put_op(dp, cldev, pcls, op + 15, 1);
  366.     if (code < 0)
  367.         return code;
  368.     } else {
  369.     long delta;
  370.     byte operand;
  371.  
  372.     switch ((cldev->color_info.depth + 15) >> 3) {
  373.         case 5:
  374.         if (!((delta = diff + cmd_delta1_32_bias) &
  375.               ~cmd_delta1_32_mask) &&
  376.             (operand =
  377.              (byte) ((delta >> 23) + ((delta >> 18) & 1))) != 0 &&
  378.             operand != 15
  379.             ) {
  380.             code = set_cmd_put_op(dp, cldev, pcls,
  381.                       (byte) (op + operand), 2);
  382.             if (code < 0)
  383.             return code;
  384.             dp[1] = (byte) (((delta >> 10) & 0300) +
  385.                     (delta >> 5) + delta);
  386.             break;
  387.         }
  388.         if (!((delta = diff + cmd_delta2_32_bias) &
  389.               ~cmd_delta2_32_mask)
  390.             ) {
  391.             code = set_cmd_put_op(dp, cldev, pcls, op_delta2, 3);
  392.             if (code < 0)
  393.             return code;
  394.             dp[1] = (byte) ((delta >> 20) + (delta >> 16));
  395.             dp[2] = (byte) ((delta >> 4) + delta);
  396.             break;
  397.         }
  398.         code = set_cmd_put_op(dp, cldev, pcls, op, 5);
  399.         if (code < 0)
  400.             return code;
  401.         *++dp = (byte) (color >> 24);
  402.         goto b3;
  403.         case 4:
  404.         if (!((delta = diff + cmd_delta1_24_bias) &
  405.               ~cmd_delta1_24_mask) &&
  406.             (operand = (byte) (delta >> 16)) != 0 &&
  407.             operand != 15
  408.             ) {
  409.             code = set_cmd_put_op(dp, cldev, pcls,
  410.                       (byte) (op + operand), 2);
  411.             if (code < 0)
  412.             return code;
  413.             dp[1] = (byte) ((delta >> 4) + delta);
  414.             break;
  415.         }
  416.         if (!((delta = diff + cmd_delta2_24_bias) &
  417.               ~cmd_delta2_24_mask)
  418.             ) {
  419.             code = set_cmd_put_op(dp, cldev, pcls, op_delta2, 3);
  420.             if (code < 0)
  421.             return code;
  422.             dp[1] = ((byte) (delta >> 13) & 0xf8) +
  423.             ((byte) (delta >> 11) & 7);
  424.             dp[2] = (byte) (((delta >> 3) & 0xe0) + delta);
  425.             break;
  426.         }
  427.         code = set_cmd_put_op(dp, cldev, pcls, op, 4);
  428.         if (code < 0)
  429.             return code;
  430. b3:        *++dp = (byte) (color >> 16);
  431.         goto b2;
  432.         case 3:
  433.         code = set_cmd_put_op(dp, cldev, pcls, op, 3);
  434.         if (code < 0)
  435.             return code;
  436. b2:        *++dp = (byte) (color >> 8);
  437.         goto b1;
  438.         case 2:
  439.         if (diff >= -7 && diff < 7) {
  440.             code = set_cmd_put_op(dp, cldev, pcls,
  441.                       op + (int)diff + 8, 1);
  442.             if (code < 0)
  443.             return code;
  444.             break;
  445.         }
  446.         code = set_cmd_put_op(dp, cldev, pcls, op, 2);
  447.         if (code < 0)
  448.             return code;
  449. b1:        dp[1] = (byte) color;
  450.     }
  451.     }
  452.     *pcolor = color;
  453.     return 0;
  454. }
  455.  
  456. /* Put out a command to set the tile colors. */
  457. int
  458. cmd_set_tile_colors(gx_device_clist_writer * cldev, gx_clist_state * pcls,
  459.             gx_color_index color0, gx_color_index color1)
  460. {
  461.     int code = 0;
  462.  
  463.     if (color0 != pcls->tile_colors[0]) {
  464.     code = cmd_put_color(cldev, pcls,
  465.                  &clist_select_tile_color0,
  466.                  color0, &pcls->tile_colors[0]);
  467.     if (code != 0)
  468.         return code;
  469.     }
  470.     if (color1 != pcls->tile_colors[1])
  471.     code = cmd_put_color(cldev, pcls,
  472.                  &clist_select_tile_color1,
  473.                  color1, &pcls->tile_colors[1]);
  474.     return code;
  475. }
  476.  
  477. /* Put out a command to set the tile phase. */
  478. int
  479. cmd_set_tile_phase(gx_device_clist_writer * cldev, gx_clist_state * pcls,
  480.            int px, int py)
  481. {
  482.     int pcsize;
  483.     byte *dp;
  484.     int code;
  485.  
  486.     pcsize = 1 + cmd_size2w(px, py);
  487.     code =
  488.     set_cmd_put_op(dp, cldev, pcls, (byte)cmd_opv_set_tile_phase, pcsize);
  489.     if (code < 0)
  490.     return code;
  491.     ++dp;
  492.     pcls->tile_phase.x = px;
  493.     pcls->tile_phase.y = py;
  494.     cmd_putxy(pcls->tile_phase, dp);
  495.     return 0;
  496. }
  497.  
  498. /* Write a command to enable or disable the logical operation. */
  499. int
  500. cmd_put_enable_lop(gx_device_clist_writer * cldev, gx_clist_state * pcls,
  501.            int enable)
  502. {
  503.     byte *dp;
  504.     int code = set_cmd_put_op(dp, cldev, pcls,
  505.                   (byte)(enable ? cmd_opv_enable_lop :
  506.                      cmd_opv_disable_lop),
  507.                   1);
  508.  
  509.     if (code < 0)
  510.     return code;
  511.     pcls->lop_enabled = enable;
  512.     return 0;
  513. }
  514.  
  515. /* Write a command to enable or disable clipping. */
  516. /* This routine is only called if the path extensions are included. */
  517. int
  518. cmd_put_enable_clip(gx_device_clist_writer * cldev, gx_clist_state * pcls,
  519.             int enable)
  520. {
  521.     byte *dp;
  522.     int code = set_cmd_put_op(dp, cldev, pcls,
  523.                   (byte)(enable ? cmd_opv_enable_clip :
  524.                      cmd_opv_disable_clip),
  525.                   1);
  526.  
  527.     if (code < 0)
  528.     return code;
  529.     pcls->clip_enabled = enable;
  530.     return 0;
  531. }
  532.  
  533. /* Write a command to set the logical operation. */
  534. int
  535. cmd_set_lop(gx_device_clist_writer * cldev, gx_clist_state * pcls,
  536.         gs_logical_operation_t lop)
  537. {
  538.     byte *dp;
  539.     uint lop_msb = lop >> 6;
  540.     int code = set_cmd_put_op(dp, cldev, pcls,
  541.                   cmd_opv_set_misc, 2 + cmd_size_w(lop_msb));
  542.  
  543.     if (code < 0)
  544.     return code;
  545.     dp[1] = cmd_set_misc_lop + (lop & 0x3f);
  546.     cmd_put_w(lop_msb, dp + 2);
  547.     pcls->lop = lop;
  548.     return 0;
  549. }
  550.  
  551. /* Disable (if default) or enable the logical operation, setting it if */
  552. /* needed. */
  553. int
  554. cmd_update_lop(gx_device_clist_writer *cldev, gx_clist_state *pcls,
  555.            gs_logical_operation_t lop)
  556. {
  557.     int code;
  558.  
  559.     if (lop == lop_default)
  560.     return cmd_disable_lop(cldev, pcls);
  561.     code = cmd_set_lop(cldev, pcls, lop);
  562.     if (code < 0)
  563.     return code;
  564.     return cmd_enable_lop(cldev, pcls);
  565. }
  566.  
  567. /* Write a parameter list */
  568. int    /* ret 0 all ok, -ve error */
  569. cmd_put_params(gx_device_clist_writer *cldev,
  570.            gs_param_list *param_list) /* NB open for READ */
  571. {
  572.     byte *dp;
  573.     int code;
  574.     byte local_buf[512];    /* arbitrary */
  575.     int param_length;
  576.  
  577.     /* Get serialized list's length + try to get it into local var if it fits. */
  578.     param_length = code =
  579.     gs_param_list_serialize(param_list, local_buf, sizeof(local_buf));
  580.     if (param_length > 0) {
  581.     /* Get cmd buffer space for serialized */
  582.     code = set_cmd_put_all_op(dp, cldev, cmd_opv_put_params,
  583.                   1 + sizeof(unsigned) + param_length);
  584.     if (code < 0)
  585.         return code;
  586.  
  587.     /* write param list to cmd list: needs to all fit in cmd buffer */
  588.     if_debug1('l', "[l]put_params, length=%d\n", param_length);
  589.     ++dp;
  590.     memcpy(dp, ¶m_length, sizeof(unsigned));
  591.     dp += sizeof(unsigned);
  592.     if (param_length > sizeof(local_buf)) {
  593.         int old_param_length = param_length;
  594.  
  595.         param_length = code =
  596.         gs_param_list_serialize(param_list, dp, old_param_length);
  597.         if (param_length >= 0)
  598.         code = (old_param_length != param_length ?
  599.             gs_note_error(gs_error_unknownerror) : 0);
  600.         if (code < 0) {
  601.         /* error serializing: back out by writing a 0-length parm list */
  602.         memset(dp - sizeof(unsigned), 0, sizeof(unsigned));
  603.         cmd_shorten_list_op(cldev, &cldev->band_range_list,
  604.                     old_param_length);
  605.         }
  606.     } else
  607.         memcpy(dp, local_buf, param_length);        /* did this when computing length */
  608.     }
  609.     return code;
  610. }
  611.  
  612. /* Initialize CCITTFax filters. */
  613. private void
  614. clist_cf_init(stream_CF_state *ss, int width)
  615. {
  616.     ss->K = -1;
  617.     ss->Columns = width;
  618.     ss->EndOfBlock = false;
  619.     ss->BlackIs1 = true;
  620.     ss->DecodedByteAlign = align_bitmap_mod;
  621. }
  622. void
  623. clist_cfe_init(stream_CFE_state *ss, int width, gs_memory_t *mem)
  624. {
  625.     s_init_state((stream_state *)ss, &s_CFE_template, mem);
  626.     s_CFE_set_defaults_inline(ss);
  627.     clist_cf_init((stream_CF_state *)ss, width);
  628.     s_CFE_template.init((stream_state *)(ss));
  629. }
  630. void
  631. clist_cfd_init(stream_CFD_state *ss, int width, int height, gs_memory_t *mem)
  632. {
  633.     s_init_state((stream_state *)ss, &s_CFD_template, mem);
  634.     s_CFD_template.set_defaults((stream_state *)ss);
  635.     clist_cf_init((stream_CF_state *)ss, width);
  636.     ss->Rows = height;
  637.     s_CFD_template.init((stream_state *)(ss));
  638. }
  639.  
  640. /* Initialize RunLength filters. */
  641. void
  642. clist_rle_init(stream_RLE_state *ss)
  643. {
  644.     s_init_state((stream_state *)ss, &s_RLE_template, (gs_memory_t *)0);
  645.     s_RLE_set_defaults_inline(ss);
  646.     s_RLE_init_inline(ss);
  647. }
  648. void
  649. clist_rld_init(stream_RLD_state *ss)
  650. {
  651.     s_init_state((stream_state *)ss, &s_RLD_template, (gs_memory_t *)0);
  652.     s_RLD_set_defaults_inline(ss);
  653.     s_RLD_init_inline(ss);
  654. }
  655.